home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / djgpp / contrib / libgrx / ndrivers / vesadrv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-03-31  |  8.1 KB  |  237 lines

  1. /**
  2.  ** VESADRV.C ---- EGA, VGA, VESA Super VGA driver for GRX 1.03
  3.  **
  4.  ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954
  5.  ** Copyright (C) 1992 Csaba Biegl, 820 Stirrup Dr, Nashville, TN 37221
  6.  ** Copyright (C) 1993 Grzegorz Mazur, gbm@ii.pw.edu.pl
  7.  **
  8.  ** This file is distributed under the terms listed in the document
  9.  ** "copying.dj", available from DJ Delorie at the address above.
  10.  ** A copy of "copying.dj" should accompany this file; if not, a copy
  11.  ** should be available from where this file was obtained.  This file
  12.  ** may not be distributed without a verbatim copy of "copying.dj".
  13.  **
  14.  ** This file is distributed WITHOUT ANY WARRANTY; without even the implied
  15.  ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  16.  **/
  17. #pragma  inline
  18.  
  19. #include <dos.h>
  20. #include "vdr.h"
  21.  
  22. char driver_name[]  = { "GRX 1.03 VESA driver" };
  23.  
  24. #define MAX_TEXT_MODES        20            /* maximum text mode table size */
  25. #define EGA_TEXT_START        6            /* start of the EGA mode table */
  26. #define EGA_TEXT_MODES        5            /* number of EGA text modes (incl end marker) */
  27. GrModeEntry text_mode_table[MAX_TEXT_MODES] = {
  28.     { 80,   25,      2,    0x007, SETUP_STANDARD },
  29.     { 40,   25,      16,    0x001, SETUP_STANDARD },
  30.     { 80,   25,      16,    0x003, SETUP_STANDARD },
  31.     { 80,   28,      16,    0x003, SETUP_8X14_FNT },
  32.     { 80,   50,      16,    0x003, SETUP_8X8_FNT  },
  33.     { 0,    0,      0,    UNSUP, 0          },
  34.     { 80,   25,      2,    0x007, SETUP_STANDARD },    /* EGA table */
  35.     { 40,   25,      16,    0x001, SETUP_STANDARD },
  36.     { 80,   25,      16,    0x003, SETUP_STANDARD },
  37.     { 80,   43,      16,    0x003, SETUP_8X8_FNT  },
  38.     { 0,    0,      0,    UNSUP, 0          }
  39. };
  40.  
  41. #define MAX_GRAPH_MODES        40            /* maximum graphics mode table size */
  42. #define EGA_GRAPH_START        8            /* start of the EGA mode table */
  43. #define EGA_GRAPH_MODES        4            /* number of EGA graphics modes (incl end marker) */
  44. GrModeEntry graphics_mode_table[MAX_GRAPH_MODES] = {
  45.     { 320,  200,  16,    0x00d, SETUP_STANDARD },
  46.     { 640,  200,  16,    0x00e, SETUP_STANDARD },
  47.     { 640,  350,  16,    0x010, SETUP_STANDARD },
  48.     { 640,  480,  16,    0x012, SETUP_STANDARD },
  49.     { 320,  200,  256,  0x013, SETUP_STANDARD },
  50.     { 320,  240,  256,  0x013, SETUP_MODE_X   },
  51.     { 360,  480,  256,  0x013, SETUP_MODE_X   },
  52.     { 0,    0,      0,    UNSUP, 0          },
  53.     { 320,  200,  16,    0x00d, SETUP_STANDARD },    /* EGA table */
  54.     { 640,  200,  16,    0x00e, SETUP_STANDARD },
  55.     { 640,  350,  16,    0x010, SETUP_STANDARD },
  56.     { 0,    0,      0,    UNSUP, 0          }
  57. };
  58.  
  59. #include "pieces/chkevga.c"
  60. #include "pieces/chkvga.c"
  61. #include "pieces/vesainfo.c"
  62. #include "pieces/addmode.c"
  63. #include "paging/vesa.c"
  64.  
  65. int get_mem_size(int scan_line_len,int rows)
  66. {
  67.     _AX = scan_line_len;
  68.     _DX = rows;
  69.     asm mul dx;
  70.     asm add ax,4095;
  71.     asm adc dx,0;
  72.     asm mov cx,12;
  73.     asm shr ax,cl;
  74.     asm mov cx,4;
  75.     asm shl dx,cl;
  76.     asm add ax,dx;
  77.     return(_AX);        /* in 4 kByte units !! */
  78. }
  79.  
  80. int do_driver_init(void)
  81. {
  82.     VgaInfoBlock *vb;
  83.     ModeInfoBlock *mb;
  84.     short modes[100];
  85.     short far *modeptr;
  86.     int mode,colors;
  87.  
  88.     if(!check_for_EGAVGA()) return(0);
  89.     if(!check_for_VGA()) {
  90.         HDR->driver_flags = GRD_EGA | GRD_NEW_DRIVER | GRD_NO_RW | GRD_128K;
  91.         HDR->memory_size = (128 / 4);
  92.         tblcopy(text_mode_table,&text_mode_table[EGA_TEXT_START],EGA_TEXT_MODES);
  93.         tblcopy(graphics_mode_table,&graphics_mode_table[EGA_GRAPH_START],EGA_GRAPH_MODES);
  94.         return(1);
  95.     }
  96.     HDR->memory_size = (256 / 4);
  97.     if((vb = VESAgetInfo()) != 0) {
  98.         for(mode = 0; (modes[mode] = vb->VideoModePtr[mode]) != (-1); mode++) ;
  99.         modeptr = modes;
  100.         if((VESAversion >= VESA_VERSION(1,2)) &&
  101.            (vb->MemorySize >= (512/64)) &&
  102.            (vb->MemorySize <= (8192/64))) {
  103.         /* VESA 1.2 is supposed to report memory size this way! */
  104.         HDR->memory_size = vb->MemorySize * (64/4);
  105.         }
  106.         while((mode = *modeptr++) != (-1)) {
  107.         if((mb = VESAgetModeInfo(mode)) == 0) continue;
  108.         if((mb->ModeAttributes & MODE_EXTINFO) == 0) {
  109.             /* I am really delighted to have this mode, but.. */
  110.             /* what can I do with it without resolution info? */
  111.             continue;
  112.         }
  113.         if(mb->ModeAttributes & MODE_ISGRAPHICS) {
  114.             if(mb->BitsPerPixel < 16)
  115.             colors = 1 << mb->BitsPerPixel;
  116.             else if(mb->BitsPerPixel > 16)
  117.             colors = 0xc000U | mb->BitsPerPixel;
  118.             else if(VESAversion >= VESA_VERSION(1,2))
  119.             colors = mb->ReservedMaskSize ? 32768U : (0xc000 + 16);
  120.             else if(HDR->driver_options & GRD_15_PLANE_MODE)
  121.             colors = 32768U;
  122.             else colors = 0xc000U + 16;
  123.             add_graphics_mode(mb->XResolution,mb->YResolution,
  124.             colors,mode,SETUP_STANDARD
  125.             );
  126.             mode = get_mem_size(mb->BytesPerScanLine,mb->YResolution);
  127.             if(mb->MemoryModel == MODEL_4PLANE) mode <<= 2;
  128.             mode = (mode + (512/4 - 1)) & ~(512/4 - 1);        /* round up to next 0.5 MB */
  129.             if(HDR->memory_size < mode) HDR->memory_size = mode;
  130.         }
  131.         else {
  132.             add_text_mode(mb->XResolution,mb->YResolution,16,mode,SETUP_STANDARD);
  133.             if(mb->YResolution == 25) {
  134.             add_text_mode(mb->XResolution,28,16,mode,SETUP_8X14_FNT);
  135.             add_text_mode(mb->XResolution,50,16,mode,SETUP_8X8_FNT);
  136.             }
  137.         }
  138.         }
  139.     }
  140.     mode = GRD_256K;
  141.     if(HDR->memory_size >= (512  / 4)) mode = GRD_512K;
  142.     if(HDR->memory_size >= (1024 / 4)) mode = GRD_1024K;
  143.     if(HDR->memory_size >= (1536 / 4)) mode = GRD_1536K;
  144.     if(HDR->memory_size >= (2048 / 4)) mode = GRD_2048K;
  145.     if(HDR->memory_size >= (3072 / 4)) mode = GRD_3072K;
  146.     if(HDR->memory_size >= (4096 / 4)) mode = GRD_4096K;
  147.     HDR->driver_flags = GRD_VGA | GRD_NEW_DRIVER | GRD_NO_RW | mode;
  148.     return(1);
  149. }
  150.  
  151. #include "pieces/textfont.c"
  152. #include "pieces/mode_x.c"
  153.  
  154. int do_mode_set(GrModeEntry *md,int noclear,int *vw,int *vh,char *vflag)
  155. {
  156.     int BIOSno,memmode,pgmode;
  157.  
  158.     switch(md->mode.vdr.custom_setup_index) {
  159.         case SETUP_8X14_FNT:  return(mode_set_8x14_font(md,noclear));
  160.         case SETUP_8X8_FNT:      return(mode_set_8x8_font(md,noclear));
  161.         case SETUP_MODE_X:      return(mode_set_256_planar(md,noclear));
  162.     }
  163.     if((BIOSno = md->mode.vdr.BIOS_mode) > 0x13) {
  164.         if(noclear) BIOSno |= 0x8000;
  165.         _AX = VESA_FUNC + VESA_SET_MODE;
  166.         _BX = BIOSno;
  167.         geninterrupt(0x10);
  168.         if(_AX != VESA_SUCCESS) return(-1);
  169.     }
  170.     else {
  171.         if(noclear) BIOSno |= 0x80;
  172.         _AX = BIOSno;
  173.         geninterrupt(0x10);
  174.     }
  175.     pgmode = setup_VESA_paging(md);
  176.     if(pgmode == (-1)) return(-1);
  177.     switch((unsigned)md->number_of_colors) {
  178.         case 2U:         memmode = GRD_1_PLANE;  break;
  179.         case 16U:         memmode = GRD_4_PLANES; break;
  180.         case 256U:         memmode = (HDR->driver_options & GRD_FAST_256_MODE) ? GRD_8_F_PLANES : GRD_8_PLANES; break;
  181.         case 32768U:     memmode = GRD_16_PLANES;    break;
  182.         case 0xc000U+16: memmode = GRD_16_R_PLANES; break;
  183.         case 0xc000U+24: memmode = GRD_24_PLANES;    break;
  184.         default:         return(-1);
  185.     }
  186.     if((md->number_of_colors > 256) && (VESAversion >= VESA_VERSION(1,2))) {
  187.         ModeInfoBlock *mb = VESAgetModeInfo(md->mode.vdr.BIOS_mode);
  188.         if(mb) {
  189.         HDR->r_mask = mb->RedMaskSize;
  190.         HDR->r_offs = mb->RedMaskPos;
  191.         HDR->g_mask = mb->GreenMaskSize;
  192.         HDR->g_offs = mb->GreenMaskPos;
  193.         HDR->b_mask = mb->BlueMaskSize;
  194.         HDR->b_offs = mb->BlueMaskPos;
  195.         HDR->f_mask = mb->ReservedMaskSize;
  196.         HDR->f_offs = mb->ReservedMaskPos;
  197.         /* is that 16 really only 15 ? */
  198.         if((memmode == GRD_16_R_PLANES) && (HDR->f_mask > 0)) memmode = GRD_16_PLANES;
  199.         }
  200.     }
  201.     if((*vw > md->width) || (*vh > md->height)) {
  202.         int virw = *vw;
  203.         int virh = *vh;
  204.         _BX = (virw > md->width) ? 0 : 1;           /* inquire only if width stays the same */
  205.         _CX = virw;
  206.         _AX = VESA_FUNC + VESA_SCAN_LNLEN;
  207.         geninterrupt(0x10);
  208.         if(_AX == VESA_SUCCESS) {
  209.         virw = _CX;
  210.         virh = _DX;
  211.         HDR->line_offset = _BX;
  212.         if((virw > md->width) || (virh > md->height)) {
  213.             *vw = virw;
  214.             *vh = virh;
  215.             *vflag = 1;
  216.         }
  217.         }
  218.     }
  219.     return((HDR->driver_flags & ~(GRD_PLANE_MASK | GRD_PAGING_MASK)) | memmode | pgmode);
  220. }
  221.  
  222. void do_screen_start_set(int *cp,int *rp)
  223. {
  224.     _CX = *cp;
  225.     _DX = *rp;
  226.     _BX = 0;
  227.     _AX = VESA_FUNC + VESA_DISP_START;
  228.     geninterrupt(0x10);
  229.     if(_AX == VESA_SUCCESS) {
  230.         *cp = _CX;
  231.         *rp = _DX;
  232.     }
  233. }
  234.  
  235. #include "pieces/vdrmain.c"
  236.  
  237.